home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
LANG
/
C
/
LIB
/
DESK
/
CORE
/
Desk
/
h_doc
/
Mem
< prev
next >
Wrap
Text File
|
1996-05-21
|
9KB
|
236 lines
/*
#### # # # #
# # # # # The FreeWare C library for
# # ## ### # # # # ### RISC OS machines
# # # # # # # # # # # ___________________________________
# # #### ### ## # # # #
# # # # # # # # # # Please refer to the accompanying
#### ### #### # # ##### # ### documentation for conditions of use
________________________________________________________________________
File: Mem.h
Author: Copyright © 1993, 1994, 1995 Jason Williams and Jason Howat
Version: 2.00 (18 Jun 1995)
Purpose: Dynamic memory manager
*/
#ifndef __Desk_Mem_h
#define __Desk_Mem_h
#ifdef __cplusplus
extern "C" {
#endif
/* "Flex" is the RISC OS Lib 'flexible' malloc for desktop tasks
* "Mem" is DeskLib's equivalent thereof.
*
* Mem memory chunks are held in a 'heap' of memory above the area grabbed
* by the SharedCLibrary for mallocs and stackspace, extending up to the end
* of the WimpSlot, which is adjusted up & down as necessary.
*
* The major feature that externally distinguishes Mem from flex() is that
* the heap is NOT compacted automatically (flex keeps the entire heap
* compacted at all times). This has several advantages:
* - You can rely on pointers remaining constant at all times between
* calls to Desk_Mem_Compact() (and other Desk_Mem_ calls if you allow it)
* - everything is a lot faster if you are allocating and/or deallocating
* many chunks in one go.
*
* The idea behind this is that you simply call Desk_Mem_Compact before calling
* Desk_Wimp_Poll - this returns free memory to the Wimp as effectively as the
* flex system did, but saves us from having to waste time on multiple
* compactions between Desk_Wimp_Polls.
*
* Automatic compaction (a la flex) can be turned on (or off) at any time,
* so the Mem system can be made to emulate Desk_flex_ if you really want it. To
* do this, set Desk_mem_autocompact to the values described below.
* NOTE that by default, Mem will only autocompact if it has no choice, but
* *may* autocompact during any Desk_Mem_ call.
*/
#ifndef __Desk_Core_h
#include "Desk.Core.h"
#endif
typedef void *Desk_mem_anchor;
/* Compaction control
* Apart from compacting when you call Desk_Mem_Compact(), Mem will also compact
* at the following times, depending on the value of Desk_mem_autocompact
*
* Desk_mem_NOCOMPACT: Auto compaction never occurs. This may be useful if
* you wish to guarantee that chunks ONLY move when you
* call Desk_Mem_Compact().
*
* Desk_mem_PARTCOMPACT: Auto compaction occurs whenever compaction might make
* an otherwise impossible memory claim possible. This
* is the recommended (and default) setting.
*
* Desk_mem_FULLCOMPACT: Auto compaction occurs every time a chunk is freed
* (the way that RISC OS Lib flex() operates). This is
* not reccommended, as it can be very inefficient.
*
* NOTE that the value of Desk_mem_autocompact may be changed at any time and
* will take immediate effect. Therefore, if you wish to ensure that
* pointers into Mem chunks remain 'safe' for a short period of time, you
* can set Desk_mem_autocompact = Desk_mem_NOCOMPACT while procssing, and return it to
* its former value when finished.
*/
extern int Desk_mem_autocompact;
typedef enum
{
Desk_mem_NOCOMPACT = 0, /* ONLY compacts if Desk_Mem_Compact called */
Desk_mem_FASTCOMPACT = 1, /* Compacts only if necessary */
Desk_mem_PARTCOMPACT = 1,
Desk_mem_FULLCOMPACT = 2 /* Compacts on every heap change */
} Desk_mem_compaction;
/* Desk_Mem_Initialise()
* Initialises the Mem system ready for use.
* Note that this locks down the malloc and stack memory area to the
* current WimpSlot size at the point of calling, and builds a Mem heap
* above this. Malloc and stack allocation will not be able to get more
* memory than is originally available in your WimpSlot, so get it right!
* Note that Desk_Mem_Initialise() provides a function to
* _kernel_register_slotextend() to stop the SharedCLibrary being able to
* overwrite the Mem heap with the stack/malloc chunks.
*/
extern Desk_bool Desk_Mem_Initialise(void);
/* Desk_Mem_Alloc()
* Attempts to allocate the given amount of memory (in bytes) in the Mem
* heap. Updates the anchor you pass in to point to this block, or to
* contain NULL if it is unable to allocate the requested memory. The
* returned block of memory starts at a word-aligned address.
* Returns Desk_bool_TRUE if it succeeded
*
* If permitted to by the setting of Desk_mem_autocompact, this call MAY
* relocate other Mem chunks.
*/
extern Desk_bool Desk_Mem_Alloc(Desk_mem_anchor *anchor, int numbytes);
/* Desk_Mem_MidExtend()
* Attempts to alter the size of a Mem chunk.
* 'at' is a byte-offset within the data chunk
* 'by' is the number of bytes to extend by (negative to reduce the chunk)
* If 'by' is positive,
* 'by' bytes of indeterminate value will be inserted at 'at',
* shifting the rest of the data up to make room
* else
* 'by' bytes of data BELOW 'at' will be deleted by moving the
* data from 'at' onwards down by 'by' bytes.
*
* Returns Desk_bool_TRUE if the extension was successful.
* The allocated memory starts at a word-aligned address
*
* If permitted to by the setting of Desk_mem_autocompact, this call MAY
* relocate other Mem chunks.
*/
extern Desk_bool Desk_Mem_MidExtend(Desk_mem_anchor *anchor, int at, int by);
/* Desk_Mem_MoveAnchor
* Allows you to move an anchor from one variable to another.
* This allows you to allocate a chunk with a temporary anchor and then
* move the anchor into permanent storage at a later time (without having
* to allocate a new chunk and copy, as is necessary under flex)
*
* Use with care - i.e. remember to check anchors to see if they are NULL
* (in which case you're using the wrong anchor!)
*
* If all goes well (i.e. 'from' was a valid chunk), *from will be set to
* NULL and *to will now point at the chunk. From this point on, the
* anchor 'to' will be adjusted whenever the chunk is moved.
*
* Otherwise, from is left as it was, and to will be set to NULL
*
* example:
* {
* char *old, *new;
* Desk_Mem_Alloc((Desk_mem_anchor *) &old, 1024); |* Get some memory *|
* if (old != NULL)
* {
* old[5] = 'a';
* Desk_Mem_MoveAnchor((Desk_mem_anchor *) &old, (Desk_mem_anchor *) &new);
* |* if 'old' was valid, 'new' now points to where old was, *|
* |* and old is now NULL *|
*
* if (new == NULL) printf("Error - old was invalid! \n");
* if (new[5] != 'a') printf("Error - Jason's code is buggy! \n");
*/
extern void Desk_Mem_MoveAnchor(Desk_mem_anchor *from, Desk_mem_anchor *to);
/* Desk_Mem_Free()
* Releases a chunk of memory back to the free pool.
* The contents of the anchor will be set to NULL to indicate it is no
* longer a valid pointer.
* If permitted to by the contents of Desk_mem_autocompact, this call MAY
* relocate other Mem chunks.
*/
extern void Desk_Mem_Free(Desk_mem_anchor *anchor);
/* Desk_Mem_Compact()
* This call compacts the Mem heap, moving all free space to the end of
* the chunk, and giving back as much memory as possible to the Wimp. This
* may result in some Mem chunks moving, so you cannot rely on anchors
* remaining the same across this call.
* Ideally, you should call this just before calling Desk_Wimp_Poll, to ensure
* the Wimp has all possible available memory (and also keep the heap
* tidy).
* Note that this may be automatically called by other Desk_Mem_ functions IF
* Desk_mem_autocompact allows it. However, it will NEVER be called if
* Desk_mem_autocompact == Desk_mem_NOCOMPACT
*/
extern void Desk_Mem_Compact(void);
/* Desk_Mem_Size()
* Returns the current size (in bytes) of a Mem chunk
*/
extern int Desk_Mem_Size(Desk_mem_anchor *anchor);
/* Desk_Mem_CheckHeap()
* Returns Desk_bool_TRUE if the heap data structure is valid (i.e. the links are
* all intact and anchors are consistent)
*/
extern Desk_bool Desk_Mem_CheckHeap(void);
#ifdef Desk_DeskLib_DEBUG
#ifdef Desk__making_Mem
#include "Debug.h"
#define Desk_debug_level Desk_mem_debuglevel
#endif
extern int Desk_mem_debuglevel;
/*
In the debug version of DeskLib, this is the Mem library's own version
of Desk_debug_level. It is initially 0; a program can set it to different
values to turn on different debug ouputs in the Mem library.
*/
#endif
#ifdef __cplusplus
}
#endif
#endif